<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>安全预警系统 - API测试控制台</title>
    <script src="lib/vue/vue.min.js"></script>
    <style>
        body {
            font-family: 'Arial', sans-serif;
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
            background-color: #f5f5f5;
        }

        .header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 30px;
            border-radius: 10px;
            text-align: center;
            margin-bottom: 30px;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
        }

        .header h1 {
            margin: 0;
            font-size: 2.5em;
            font-weight: 300;
        }

        .header p {
            margin: 10px 0 0 0;
            opacity: 0.9;
            font-size: 1.1em;
        }

        .api-section {
            background: white;
            margin-bottom: 30px;
            border-radius: 10px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
            overflow: hidden;
        }

        .api-header {
            background: #f8f9fa;
            padding: 20px;
            border-bottom: 1px solid #e9ecef;
            cursor: pointer;
            transition: background-color 0.3s;
        }

        .api-header:hover {
            background: #e9ecef;
        }

        .api-header h3 {
            margin: 0;
            color: #495057;
            font-size: 1.3em;
        }

        .api-header .method {
            display: inline-block;
            padding: 4px 12px;
            border-radius: 4px;
            color: white;
            font-size: 0.8em;
            font-weight: bold;
            margin-right: 10px;
        }

        .method.post { background: #28a745; }
        .method.get { background: #007bff; }

        .api-content {
            padding: 20px;
        }

        .form-group {
            margin-bottom: 20px;
        }

        label {
            display: block;
            margin-bottom: 8px;
            font-weight: bold;
            color: #495057;
        }

        input, textarea, select {
            width: 100%;
            padding: 12px;
            border: 1px solid #ddd;
            border-radius: 6px;
            box-sizing: border-box;
            font-size: 14px;
        }

        textarea {
            resize: vertical;
            min-height: 100px;
        }

        .form-row {
            display: flex;
            gap: 15px;
        }

        .form-row .form-group {
            flex: 1;
        }

        button {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 12px 24px;
            border: none;
            border-radius: 6px;
            cursor: pointer;
            font-size: 16px;
            font-weight: 500;
            transition: all 0.3s;
            margin-right: 10px;
        }

        button:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
        }

        button:disabled {
            opacity: 0.6;
            cursor: not-allowed;
            transform: none;
        }

        .response-section {
            margin-top: 20px;
            padding: 15px;
            background: #f8f9fa;
            border-radius: 6px;
            border: 1px solid #e9ecef;
        }

        .response-section h4 {
            margin-top: 0;
            color: #495057;
        }

        .response-content {
            background: white;
            padding: 15px;
            border-radius: 4px;
            border: 1px solid #dee2e6;
            max-height: 300px;
            overflow-y: auto;
            font-family: 'Courier New', monospace;
            font-size: 13px;
            line-height: 1.5;
        }

        .status {
            display: inline-block;
            padding: 6px 12px;
            border-radius: 20px;
            font-size: 12px;
            font-weight: bold;
            margin-bottom: 10px;
        }

        .status.ready { background: #d4edda; color: #155724; }
        .status.loading { background: #fff3cd; color: #856404; }
        .status.success { background: #d1ecf1; color: #0c5460; }
        .status.error { background: #f8d7da; color: #721c24; }

        .file-upload {
            position: relative;
            overflow: hidden;
            display: inline-block;
        }

        .file-upload input[type=file] {
            position: absolute;
            left: -9999px;
        }

        .file-upload label {
            background: #6c757d;
            color: white;
            padding: 10px 20px;
            border-radius: 6px;
            cursor: pointer;
            font-weight: normal;
            margin: 0;
        }

        .file-upload label:hover {
            background: #5a6268;
        }

        .collapsed {
            display: none;
        }

        .json-viewer {
            background: #2d3748;
            color: #e2e8f0;
            padding: 15px;
            border-radius: 6px;
            font-family: 'Courier New', monospace;
            font-size: 13px;
            line-height: 1.5;
            overflow-x: auto;
        }

        .json-key { color: #9f7aea; }
        .json-string { color: #68d391; }
        .json-number { color: #f687b3; }
        .json-boolean { color: #fbb6ce; }
    </style>
</head>
<body>
<div id="app">
    <div class="header">
        <h1>🛡️ 安全预警系统</h1>
        <p>API测试控制台 - 支持所有接口的在线测试</p>
    </div>

    <!-- 1. 知识库问答接口 -->
    <div class="api-section">
        <div class="api-header" @click="toggleSection('knowledge')">
            <span class="method post">POST</span>
            <span class="method get">GET</span>
            <h3>/knowledge_base/answer - 知识库智能问答</h3>
        </div>
        <div class="api-content" :class="{ collapsed: !sections.knowledge }">
            <div class="form-row">
                <div class="form-group">
                    <label>问题 *</label>
                    <textarea v-model="knowledge.query" placeholder="请输入您的问题..."></textarea>
                </div>
                <div class="form-group">
                    <label>查询类型</label>
                    <select v-model="knowledge.type">
                        <option value="1">常规问答</option>
                        <option value="2">专业咨询</option>
                    </select>
                </div>
            </div>
            <div class="form-row">
                <div class="form-group">
                    <label>权限类型</label>
                    <select v-model="knowledge.permission_type">
                        <option value="1">公开访问</option>
                        <option value="2">权限限制</option>
                    </select>
                </div>
                <div class="form-group">
                    <label>权限列表 (逗号分隔)</label>
                    <input v-model="knowledge.permission_set" placeholder="如: user1,user2">
                </div>
            </div>
            <div class="form-group">
                <label>文件过滤 (逗号分隔)</label>
                <input v-model="knowledge.query_file" placeholder="如: file1,file2">
            </div>
            <button @click="testKnowledgeBase('GET')" :disabled="!knowledge.query">GET 请求</button>
            <button @click="testKnowledgeBase('POST')" :disabled="!knowledge.query">POST 请求</button>
            
            <div class="response-section">
                <h4>
                    <span class="status" :class="knowledge.status">{{ knowledge.statusText }}</span>
                </h4>
                <div class="response-content" v-html="knowledge.response"></div>
            </div>
        </div>
    </div>

    <!-- 2. 事件处理接口 -->
    <div class="api-section">
        <div class="api-header" @click="toggleSection('event')">
            <span class="method post">POST</span>
            <span class="method get">GET</span>
            <h3>/event_handle - 安全事件处理</h3>
        </div>
        <div class="api-content" :class="{ collapsed: !sections.event }">
            <div class="form-row">
                <div class="form-group">
                    <label>事件名称 *</label>
                    <input v-model="event.event_name" placeholder="如: 数据泄露事件">
                </div>
                <div class="form-group">
                    <label>事件级别</label>
                    <select v-model="event.event_level">
                        <option value="低">低</option>
                        <option value="中">中</option>
                        <option value="高">高</option>
                        <option value="紧急">紧急</option>
                    </select>
                </div>
            </div>
            <div class="form-row">
                <div class="form-group">
                    <label>组织名称</label>
                    <input v-model="event.org_name" placeholder="如: 测试组织">
                </div>
                <div class="form-group">
                    <label>告警名称</label>
                    <input v-model="event.alarm_name" placeholder="如: 异常访问告警">
                </div>
            </div>
            <div class="form-row">
                <div class="form-group">
                    <label>告警类型</label>
                    <input v-model="event.alarm_type" placeholder="如: 数据安全">
                </div>
                <div class="form-group">
                    <label>告警描述</label>
                    <textarea v-model="event.alarm_desc" placeholder="描述具体的告警信息..."></textarea>
                </div>
            </div>
            <button @click="testEventHandle('GET')" :disabled="!event.event_name">GET 请求</button>
            <button @click="testEventHandle('POST')" :disabled="!event.event_name">POST 请求</button>
            
            <div class="response-section">
                <h4>
                    <span class="status" :class="event.status">{{ event.statusText }}</span>
                </h4>
                <div class="response-content" v-html="event.response"></div>
            </div>
        </div>
    </div>

    <!-- 3. 文件上传接口 -->
    <div class="api-section">
        <div class="api-header" @click="toggleSection('upload')">
            <span class="method post">POST</span>
            <h3>/knowledge_base/upload - 文档上传管理</h3>
        </div>
        <div class="api-content" :class="{ collapsed: !sections.upload }">
            <div class="form-row">
                <div class="form-group">
                    <label>操作类型</label>
                    <select v-model="upload.op_type">
                        <option value="1">上传文件</option>
                        <option value="2">删除文件</option>
                    </select>
                </div>
                <div class="form-group">
                    <label>文件ID *</label>
                    <input v-model="upload.file_id" placeholder="如: doc_001">
                </div>
            </div>
            <div v-if="upload.op_type === '1'" class="form-row">
                <div class="form-group">
                    <label>选择文件</label>
                    <div class="file-upload">
                        <input type="file" id="file-upload" @change="handleFileSelect" accept=".pdf,.doc,.docx,.txt">
                        <label for="file-upload">选择文件</label>
                    </div>
                    <div v-if="upload.selectedFile" style="margin-top: 10px; color: #666;">
                        已选择: {{ upload.selectedFile.name }}
                    </div>
                </div>
                <div class="form-group">
                    <label>文件名称</label>
                    <input v-model="upload.file_name" placeholder="如: 安全管理规范.pdf">
                </div>
            </div>
            <div v-if="upload.op_type === '1'" class="form-row">
                <div class="form-group">
                    <label>权限类型</label>
                    <select v-model="upload.permission_type">
                        <option value="1">公开访问</option>
                        <option value="2">权限限制</option>
                    </select>
                </div>
                <div class="form-group">
                    <label>权限列表 (逗号分隔)</label>
                    <input v-model="upload.permission_set" placeholder="如: user1,user2">
                </div>
            </div>
            <button @click="testUpload" :disabled="!upload.file_id || (upload.op_type === '1' && !upload.selectedFile)">
                {{ upload.op_type === '1' ? '上传文件' : '删除文件' }}
            </button>
            
            <div class="response-section">
                <h4>
                    <span class="status" :class="upload.status">{{ upload.statusText }}</span>
                </h4>
                <div class="response-content" v-html="upload.response"></div>
            </div>
        </div>
    </div>

    <!-- 4. 文档合规检查接口 -->
    <div class="api-section">
        <div class="api-header" @click="toggleSection('compliance')">
            <span class="method post">POST</span>
            <h3>/knowledge_base/document_compliance - 文档合规检查</h3>
        </div>
        <div class="api-content" :class="{ collapsed: !sections.compliance }">
            <div class="form-row">
                <div class="form-group">
                    <label>选择文档</label>
                    <div class="file-upload">
                        <input type="file" id="compliance-file" @change="handleComplianceFileSelect" accept=".pdf,.doc,.docx,.txt">
                        <label for="compliance-file">选择文档</label>
                    </div>
                    <div v-if="compliance.selectedFile" style="margin-top: 10px; color: #666;">
                        已选择: {{ compliance.selectedFile.name }}
                    </div>
                </div>
                <div class="form-group">
                    <label>文件ID (可选)</label>
                    <input v-model="compliance.file_id" placeholder="如: comp_001">
                </div>
            </div>
            <button @click="testCompliance" :disabled="!compliance.selectedFile">开始合规检查</button>
            
            <div class="response-section">
                <h4>
                    <span class="status" :class="compliance.status">{{ compliance.statusText }}</span>
                </h4>
                <div class="response-content" v-html="compliance.response"></div>
            </div>
        </div>
    </div>

    <!-- 5. 文档列表查询接口 -->
    <div class="api-section">
        <div class="api-header" @click="toggleSection('documents')">
            <span class="method get">GET</span>
            <h3>/knowledge_base/documents - 文档列表查询</h3>
        </div>
        <div class="api-content" :class="{ collapsed: !sections.documents }">
            <div class="form-group">
                <label>说明</label>
                <p style="color: #666; margin: 0;">获取系统中所有已上传的文档列表，包括文件ID、标题、权限设置等信息。</p>
            </div>
            <button @click="testDocuments">查询文档列表</button>
            
            <div class="response-section">
                <h4>
                    <span class="status" :class="documents.status">{{ documents.statusText }}</span>
                </h4>
                <div class="response-content" v-html="documents.response"></div>
            </div>
            
            <!-- 文档列表展示 -->
            <div v-if="documents.list.length > 0" class="response-section">
                <h4>文档列表 (共 {{ documents.list.length }} 个文档)</h4>
                <div style="overflow-x: auto;">
                    <table style="width: 100%; border-collapse: collapse; font-size: 13px;">
                        <thead>
                            <tr style="background: #f8f9fa;">
                                <th style="border: 1px solid #ddd; padding: 8px; text-align: left;">文件ID</th>
                                <th style="border: 1px solid #ddd; padding: 8px; text-align: left;">文件标题</th>
                                <th style="border: 1px solid #ddd; padding: 8px; text-align: left;">权限设置</th>
                                <th style="border: 1px solid #ddd; padding: 8px; text-align: center;">文档块数</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr v-for="doc in documents.list" :key="doc.file_id">
                                <td style="border: 1px solid #ddd; padding: 8px; font-family: monospace;">{{ doc.file_id }}</td>
                                <td style="border: 1px solid #ddd; padding: 8px;">{{ doc.title }}</td>
                                <td style="border: 1px solid #ddd; padding: 8px;">{{ doc.permission_set }}</td>
                                <td style="border: 1px solid #ddd; padding: 8px; text-align: center;">{{ doc.doc_count }}</td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            sections: {
                knowledge: true,
                event: false,
                upload: false,
                compliance: false,
                documents: false
            },
            knowledge: {
                query: '',
                type: '1',
                permission_type: '1',
                permission_set: '',
                query_file: '',
                response: '',
                status: 'ready',
                statusText: '准备就绪',
                eventSource: null
            },
            event: {
                event_name: '',
                event_level: '中',
                org_name: '',
                alarm_name: '',
                alarm_type: '',
                alarm_desc: '',
                response: '',
                status: 'ready',
                statusText: '准备就绪',
                eventSource: null
            },
            upload: {
                op_type: '1',
                file_id: '',
                file_name: '',
                permission_type: '1',
                permission_set: '',
                selectedFile: null,
                response: '',
                status: 'ready',
                statusText: '准备就绪'
            },
            compliance: {
                file_id: '',
                selectedFile: null,
                response: '',
                status: 'ready',
                statusText: '准备就绪',
                eventSource: null
            },
            documents: {
                response: '',
                status: 'ready',
                statusText: '准备就绪',
                list: []
            }
        },
        methods: {
            toggleSection(section) {
                this.sections[section] = !this.sections[section];
            },
            
            testKnowledgeBase(method) {
                this.knowledge.response = '';
                this.knowledge.status = 'loading';
                this.knowledge.statusText = '正在处理...';
                
                if (this.knowledge.eventSource) {
                    this.knowledge.eventSource.close();
                }
                
                const params = {
                    query: this.knowledge.query,
                    type: parseInt(this.knowledge.type),
                    permission_type: parseInt(this.knowledge.permission_type),
                    permission_set: this.knowledge.permission_set.split(',').filter(x => x.trim()),
                    query_file: this.knowledge.query_file.split(',').filter(x => x.trim()),
                    context: []
                };
                
                if (method === 'GET') {
                    const url = `http://localhost:8080/knowledge_base/answer?query=${encodeURIComponent(this.knowledge.query)}&type=${params.type}`;
                    this.knowledge.eventSource = new EventSource(url);
                    this.handleSSEResponse(this.knowledge.eventSource, this.knowledge);
                } else {
                    this.handlePostSSE('http://localhost:8080/knowledge_base/answer', params, this.knowledge);
                }
            },
            
            testEventHandle(method) {
                this.event.response = '';
                this.event.status = 'loading';
                this.event.statusText = '正在处理...';
                
                if (this.event.eventSource) {
                    this.event.eventSource.close();
                }
                
                const params = {
                    event_name: this.event.event_name,
                    event_level: this.event.event_level,
                    event_time: Math.floor(Date.now() / 1000),
                    org_name: this.event.org_name,
                    alarm_name: this.event.alarm_name,
                    alarm_type: this.event.alarm_type,
                    alarm_desc: this.event.alarm_desc,
                    alarm_detail: [],
                    stream: true
                };
                
                if (method === 'GET') {
                    const queryString = Object.keys(params).map(key => 
                        `${key}=${encodeURIComponent(params[key])}`
                    ).join('&');
                    const url = `http://localhost:8080/event_handle?${queryString}`;
                    this.event.eventSource = new EventSource(url);
                    this.handleSSEResponse(this.event.eventSource, this.event);
                } else {
                    this.handlePostSSE('http://localhost:8080/event_handle', params, this.event);
                }
            },
            
            testUpload() {
                this.upload.response = '';
                this.upload.status = 'loading';
                this.upload.statusText = '正在处理...';
                
                const formData = new FormData();
                formData.append('op_type', this.upload.op_type);
                formData.append('file_id', this.upload.file_id);
                
                if (this.upload.op_type === '1' && this.upload.selectedFile) {
                    formData.append('file', this.upload.selectedFile);
                    formData.append('file_name', this.upload.file_name || this.upload.selectedFile.name);
                    formData.append('permission_type', this.upload.permission_type);
                    formData.append('permission_set', this.upload.permission_set);
                }
                
                fetch('http://localhost:8080/knowledge_base/upload', {
                    method: 'POST',
                    body: formData
                })
                .then(response => response.json())
                .then(data => {
                    this.upload.response = this.formatJSON(data);
                    this.upload.status = data.code === 0 ? 'success' : 'error';
                    this.upload.statusText = data.msg || '操作完成';
                })
                .catch(error => {
                    this.upload.response = `错误: ${error.message}`;
                    this.upload.status = 'error';
                    this.upload.statusText = '请求失败';
                });
            },
            
            testCompliance() {
                this.compliance.response = '';
                this.compliance.status = 'loading';
                this.compliance.statusText = '正在分析...';
                
                if (this.compliance.eventSource) {
                    this.compliance.eventSource.close();
                }
                
                const formData = new FormData();
                formData.append('file', this.compliance.selectedFile);
                if (this.compliance.file_id) {
                    formData.append('file_id', this.compliance.file_id);
                }
                
                fetch('http://localhost:8080/knowledge_base/document_compliance', {
                    method: 'POST',
                    body: formData
                })
                .then(response => {
                    if (!response.ok) {
                        throw new Error(`HTTP error! status: ${response.status}`);
                    }
                    const reader = response.body.getReader();
                    const decoder = new TextDecoder();
                    
                    const read = () => {
                        reader.read().then(({ done, value }) => {
                            if (done) {
                                this.compliance.status = 'success';
                                this.compliance.statusText = '分析完成';
                                return;
                            }
                            
                            const chunk = decoder.decode(value);
                            const messages = chunk.split('\n\n');
                            
                            messages.forEach(message => {
                                if (message.startsWith('data: ')) {
                                    const data = message.substring(6);
                                    if (data === '[DONE]') {
                                        this.compliance.status = 'success';
                                        this.compliance.statusText = '分析完成';
                                    } else {
                                        try {
                                            const parsed = JSON.parse(data);
                                            this.compliance.response += parsed.content || '';
                                        } catch (e) {
                                            this.compliance.response += data;
                                        }
                                    }
                                }
                            });
                            
                            read();
                        });
                    };
                    
                    read();
                })
                .catch(error => {
                    this.compliance.response = `错误: ${error.message}`;
                    this.compliance.status = 'error';
                    this.compliance.statusText = '分析失败';
                });
            },
            
            handleSSEResponse(eventSource, target) {
                eventSource.onmessage = (event) => {
                    if (event.data === '[DONE]') {
                        eventSource.close();
                        target.status = 'success';
                        target.statusText = '处理完成';
                        return;
                    }
                    
                    try {
                        const data = JSON.parse(event.data);
                        if (data.type === 'problem_detail') {
                            target.response += `<div style="color: #007bff; font-weight: bold;">问题详情:</div>${data.content}<br><br>`;
                        } else if (data.type === 'violation_detail') {
                            target.response += `<div style="color: #dc3545; font-weight: bold;">违规详情:</div>${data.content}<br><br>`;
                        } else if (data.type === 'suggestion') {
                            target.response += `<div style="color: #28a745; font-weight: bold;">处置建议:</div>${data.content}`;
                        } else {
                            target.response += data.content || '';
                        }
                    } catch (e) {
                        target.response += event.data;
                    }
                };
                
                eventSource.onerror = (error) => {
                    target.response = `连接错误: ${error.message || '未知错误'}`;
                    target.status = 'error';
                    target.statusText = '连接失败';
                    eventSource.close();
                };
            },
            
            handlePostSSE(url, params, target) {
                fetch(url, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify(params)
                })
                .then(response => {
                    if (!response.ok) {
                        throw new Error(`HTTP error! status: ${response.status}`);
                    }
                    
                    const reader = response.body.getReader();
                    const decoder = new TextDecoder();
                    
                    const read = () => {
                        reader.read().then(({ done, value }) => {
                            if (done) {
                                target.status = 'success';
                                target.statusText = '处理完成';
                                return;
                            }
                            
                            const chunk = decoder.decode(value);
                            const messages = chunk.split('\n\n');
                            
                            messages.forEach(message => {
                                if (message.startsWith('data: ')) {
                                    const data = message.substring(6);
                                    if (data === '[DONE]') {
                                        target.status = 'success';
                                        target.statusText = '处理完成';
                                    } else {
                                        try {
                                            const parsed = JSON.parse(data);
                                            if (parsed.type === 'problem_detail') {
                                                target.response += `<div style="color: #007bff; font-weight: bold;">问题详情:</div>${parsed.content}<br><br>`;
                                            } else if (parsed.type === 'violation_detail') {
                                                target.response += `<div style="color: #dc3545; font-weight: bold;">违规详情:</div>${parsed.content}<br><br>`;
                                            } else if (parsed.type === 'suggestion') {
                                                target.response += `<div style="color: #28a745; font-weight: bold;">处置建议:</div>${parsed.content}`;
                                            } else {
                                                target.response += parsed.content || '';
                                            }
                                        } catch (e) {
                                            target.response += data;
                                        }
                                    }
                                }
                            });
                            
                            read();
                        });
                    };
                    
                    read();
                })
                .catch(error => {
                    target.response = `错误: ${error.message}`;
                    target.status = 'error';
                    target.statusText = '请求失败';
                });
            },
            
            handleFileSelect(event) {
                this.upload.selectedFile = event.target.files[0];
                if (this.upload.selectedFile && !this.upload.file_name) {
                    this.upload.file_name = this.upload.selectedFile.name;
                }
            },
            
            handleComplianceFileSelect(event) {
                this.compliance.selectedFile = event.target.files[0];
            },
            
            testDocuments() {
                this.documents.response = '';
                this.documents.status = 'loading';
                this.documents.statusText = '正在查询...';
                this.documents.list = [];
                
                fetch('http://localhost:8080/knowledge_base/documents', {
                    method: 'GET',
                    headers: {
                        'Content-Type': 'application/json'
                    }
                })
                .then(response => response.json())
                .then(data => {
                    this.documents.response = this.formatJSON(data);
                    this.documents.status = data.code === 0 ? 'success' : 'error';
                    this.documents.statusText = data.msg || '查询完成';
                    
                    if (data.code === 0 && data.data) {
                        this.documents.list = data.data;
                    }
                })
                .catch(error => {
                    this.documents.response = `错误: ${error.message}`;
                    this.documents.status = 'error';
                    this.documents.statusText = '查询失败';
                });
            },
            
            formatJSON(obj) {
                return `<div class="json-viewer">${JSON.stringify(obj, null, 2)}</div>`;
            }
        },
        beforeDestroy() {
            if (this.knowledge.eventSource) this.knowledge.eventSource.close();
            if (this.event.eventSource) this.event.eventSource.close();
            if (this.compliance.eventSource) this.compliance.eventSource.close();
        }
    });
</script>
</body>
</html>